/* << fastinsert report library >> PdfPage.h Oct 31, 2010
 *
 * 	http://code.google.com/p/libfir
 *
 * Copyright (c) 2005 Pavlo Drobov (drobov.pavel@gmail.com)
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 */

#ifndef PDFPAGE_H_
#define PDFPAGE_H_

#include <math.h>
#include <sys/stat.h>
//#include <string>

#include "hpdf.h"

#include "Debug.h"

#define DEFAULT_PDF_ENCODE	 HPDF_ENCODING_CP1251 //"CP1251"

const double PI = 4.0f *atan(1.0f);
#define ROTATE90 	(90.0f / 180.0f * PI)
#define ROTATE45 	(45.0f / 180.0f * PI)

//#define RESOLUTION_DPI 	144.0f
#define RESOLUTION_DPI 		72.0f
#define A4_WIDTH			210.0f
#define A4_HIGHT			297.0f

#define mm2pixel(mm,dpi) 	(mm * dpi / 25.4f)
#define pixel2mm(px,dpi) 	(dpi / (25.4f * px))


namespace dasco
{
namespace report
{

//! \struct dashLine
//! \brief describe dash line (color grade, etc.)
struct dashLine
{
	float gray;
	float brushWidth;
	const HPDF_UINT16 * dashFactor;
	dashLine()
		: gray(0.0f)
		 ,brushWidth(0.5f)
		 ,dashFactor(NULL)
	 {}
};

//! \struct renderLinePx
//! \brief describe dash line (coordinate)
struct renderLinePx : dashLine
{
	float srcX,srcY,dstX,dstY;

	friend Debug& operator << (Debug& debug, renderLinePx& px)
	{
		debug << "render line; srcX:" << px.srcX  << " srcY:" << px.srcY
				<< " dstX:" << px.dstX  << " dstY:" << px.dstY;
		return debug;
	}
};

//! \struct renderZebraPx
//! \brief describe "Zebra" for header
struct renderZebraPx : dashLine
{
	float srcX,srcY, width, hight, step;
	renderZebraPx() : step(3.0f)
	{}

	friend Debug& operator << (Debug& debug, renderZebraPx& px)
	{
		debug << "render zebra; srcX:" << px.srcX  << " srcY:" << px.srcY
				<< " width:" << px.width  << " hight:" << px.hight;
		return debug;
	}
};

//! \struct matrix
//! \brief the geometric matrix for turn a text into pdf page
struct matrix
{
	float srcX, srcY, a, b,c,d;
	matrix(float x, float y)
		:srcX(x),srcY(y)
		,a(::cos(ROTATE90))
		,b(::sin(ROTATE90))
		,c(-::sin(ROTATE90))
		,d(::cos(ROTATE90))
	{
	}
	void stretchOutW(float stretch)
	{
		a *= stretch;
		b *= stretch;
	}

	void stretchOutH(float stretch)
	{
		c *= stretch;
		d *= stretch;
	}
};

//! \class PdfPage
//! \brief A page of PDF document
class PdfPage
{
public:
	PdfPage(const HPDF_Doc&);

	virtual ~PdfPage();

	void setWidth(const float);
	void setHeight(const float);

	float getWidth() const;
	float getHeight() const;

	void setResolution(const float = 72.0f);

	void setSize(const float,const float);
	void setTextRenderingMode(const HPDF_TextRenderingMode = HPDF_FILL);


	HPDF_Destination createDestination() const;

	void setFontAndSize(const HPDF_Font&, const float);
	HPDF_Page getHPDF_Page() const {return page;};

	//text manipulate
	void beginText() const;
	void endText() const;
	void setTextMatrix(const matrix*);


	void renderText(const float,const float,const char*,bool = true);
	void showText(const char*);

	void renderLine(const renderLinePx*);
	void renderZebra(const renderZebraPx*);


private:
	HPDF_Page page;
};


}} //end namespace dasco::report

#endif /* PDFPAGE_H_ */
